package com.wstuo.common.security.service;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.security.auth.login.Configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.security.dao.ILDAPAuthenticationSettingDAO;
import com.wstuo.common.security.dto.LDAPAuthenticationSettingDTO;
import com.wstuo.common.security.entity.LDAPAuthenticationSetting;
import com.wstuo.common.security.utils.AppConfigUtils;
import com.wstuo.common.util.StringUtils;

/**
 * LDAP验证Service类
 */
public class LDAPAuthenticationSettingService implements ILDAPAuthenticationSettingService {

    private static final Logger LOGGER = Logger.getLogger(LDAPAuthenticationSettingService.class);

	@Autowired
	private ILDAPAuthenticationSettingDAO ldapAuthenticationSettingDAO;
	@Autowired
	private ILDAPService ldapService;
	/**
	 * 获取LDAP验证配置信息
	 * @return LDAPAuthenticationSettingDTO
	 */
	@Transactional
	public LDAPAuthenticationSettingDTO findLDAPAuthenticationSetting(){
		List<LDAPAuthenticationSetting> list=ldapAuthenticationSettingDAO.findAll();
		LDAPAuthenticationSettingDTO dto=new LDAPAuthenticationSettingDTO();
		if(list!=null && list.size()>0){
			LDAPAuthenticationSetting entity=list.get(0);
			LDAPAuthenticationSettingDTO.entity2dto(entity, dto);
		}
		return dto;
	};
	
	
	/**
	 * 保存LDAP验证配置信息
	 * @param dto
	 */
	@Transactional
	public void saveLDAPAuthenticationSetting(LDAPAuthenticationSettingDTO dto){
		LDAPAuthenticationSetting entity = ldapAuthenticationSettingDAO.findById(dto.getLdapId());
		if(entity==null)
			entity = new LDAPAuthenticationSetting();
		LDAPAuthenticationSettingDTO.dto2entity(dto, entity);
		ldapAuthenticationSettingDAO.merge(entity);
		this.jaaswriteconfiguration(dto);
	};
	/**
	 * Martin 写入配置
	 * @param dto
	 */
	@Transactional
	public void jaaswriteconfiguration(LDAPAuthenticationSettingDTO dto){
		String jaasPath = AppConfigUtils.getInstance().getCustomJAASPath();
		String format="";
		if(StringUtils.hasText(dto.getSearchBase())){
			String[] resources=dto.getSearchBase().toString().split(",");
			if (resources != null && resources.length > 0) {
				for(String re:resources){
					String[] res =re.toString().split("=");
					if(format=="" && res.length==2){
						format=res[1];
					}else if(res.length==2){
						format=format+"."+res[1];
					}
				}
			}
		}
		File loginConfFile = new File(jaasPath+"//login.conf");
		File krb5File = new File(jaasPath+"//krb5.ini");
		File testFile = new File(jaasPath+"//test.conf");
		FileWriter loginConfFileWriter = null;
		FileWriter krb5FileWriter = null;
		FileWriter testFileWriter = null;
		try {
			
			StringBuffer loginConfStr = new StringBuffer();
			loginConfStr.append(dto.assemblyDBLoginPapers());
			
			loginConfFileWriter = new FileWriter(loginConfFile);
			krb5FileWriter = new FileWriter(krb5File);
			testFileWriter = new FileWriter(testFile);
			PrintWriter loginConfFileprinter = new PrintWriter(loginConfFileWriter);
			PrintWriter krb5Fileprinter = new PrintWriter(krb5FileWriter);
			PrintWriter testFileprinter = new PrintWriter(testFileWriter);
			
			//Test
			testFileprinter.printf(dto.assemblytestPapers(format));
			Configuration.getConfiguration().refresh();
			//LDAP
			if(dto.getEnableAuthentication() && ldapService.connTestldap(dto)){//判断是否启用并且配置是否正确
				if("OpenLDAP".equals(dto.getLdapType())){
					loginConfStr.append(dto.assemblyLDAPLoginPapers());
				}else if("Sun_One_Directory_Server".equals(dto.getLdapType())){
					loginConfStr.append(dto.assemblySunOneLoginPapers());
				}else{
					loginConfStr.append(dto.assemblyLDAPVerifyPapers(format));
				}
			}
			
			//Kerberos
			if(dto.getKerberosEnableAuthentication() && ldapService.connTestkerberos(dto)){//判断是否启用并且配置是否正确
				loginConfStr.append(dto.assemblyKrb5LoginPapers());
				krb5Fileprinter.printf(dto.assemblyKrbPapers());
			}
			
			loginConfStr.append("\r\n};");
			loginConfFileprinter.printf(loginConfStr.toString());
			loginConfFileprinter.close();
			krb5Fileprinter.close();
			testFileprinter.close();
			Configuration.getConfiguration().refresh();
			
		} catch (IOException e) {
			LOGGER.error("Failed to write to a file");
		} finally {
			try {
				if(testFileWriter!=null){
					testFileWriter.close();
				}
				if(krb5FileWriter!=null){
					krb5FileWriter.close();
				}
				if(loginConfFileWriter!=null){
					loginConfFileWriter.close();
				}
			} catch (IOException e) {
				LOGGER.error(e);
			}
			
		}
	}
}
